home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 / IRIX 6.2 CD2.iso / dist / print.idb / usr / lib / lputil.z / lputil
Text File  |  1996-06-10  |  23KB  |  955 lines

  1. #!/bin/sh
  2. #
  3. #**************************************************************************
  4. #*
  5. #*           Copyright (c) 1993 Silicon Graphics, Inc.
  6. #*            All Rights Reserved
  7. #*
  8. #* RESTRICTED RIGHTS LEGEND:
  9. #*
  10. #* Use, duplication or disclosure by the Government is subject to
  11. #* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
  12. #* Technical Data and Computer Software clause at DFARS 52.227-7013,
  13. #* and/or in similar or successor clauses in the FAR, DOD or NASA FAR
  14. #* Supplement. Unpublished - rights reserved under the Copyright Laws of
  15. #* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
  16. #* Shoreline Blvd., Mountain View, CA 94039-7311
  17. #**************************************************************************
  18. #*
  19. #* File: lputil
  20. #*
  21. #* $Revision: 1.56 $
  22. #*
  23. #* Description:
  24. #*    Printer utility script for use by administration tools.
  25. #*
  26. #*    This script is used by higher level commands and scripts to perform
  27. #*    lp system administration.  This script handles adding, deleting,
  28. #*    removing and typing of printers.
  29. #*
  30. #**************************************************************************
  31.  
  32. # Make sure we have a sane umask so that lp can read files we create
  33.  
  34. umask 022
  35.  
  36. # Reset path since we might spawn daemons
  37.  
  38. PATH=/usr/bsd:/bin:/usr/bin:/usr/sbin:/etc:/usr/etc
  39.  
  40. # Directories
  41.  
  42. X11_DIR=/usr/lib/X11
  43. OLD_SPOOL_DIR=/usr/spool/lp            # For 4.0 compatibility
  44. SPOOL_DIR=/var/spool/lp                # New location in 5.0
  45. REMOTE_MEMBER_DIR=$OLD_SPOOL_DIR/member        # For 4.0 compatibility
  46. REMOTE_INTER_DIR=$OLD_SPOOL_DIR/interface
  47. REMOTE_INTERGUI_DIR=$OLD_SPOOL_DIR/gui_interface
  48. REMOTE_APP_DEFS_DIR=$X11_DIR/app-defaults
  49. REMOTE_LANG_APP_DIR=$X11_DIR/$LANG/app-defaults
  50. POD_DIR=$SPOOL_DIR/pod
  51. MEMBER_DIR=$SPOOL_DIR/member
  52. MODELGUI_DIR=$SPOOL_DIR/gui_model
  53. INTERGUI_DIR=$SPOOL_DIR/gui_interface
  54. SETTINGS_DIR=$SPOOL_DIR/settings
  55. DATA_DIR=/usr/lib/print/data
  56. ACTIVEICON_DIR=$SPOOL_DIR/activeicons
  57. SPOOL_APP_DEFS_DIR=$SPOOL_DIR/app-defaults
  58. PSRIP_PARAMS_DIR=$SPOOL_DIR/psparams
  59.  
  60. # Global variables
  61.  
  62. REMOTE_LOGIN_ID=lp
  63. ACTIVEICON_TEMPLATE_FILENAME=$DATA_DIR/activeicon_template
  64.  
  65.  
  66. #
  67. # This routine catches the return exit code of the previous command
  68. # and exits if there was any trouble.
  69. #
  70. rcexit()
  71. {
  72.     rc=$?
  73.     if [ $rc != 0 ]; then    # exit with an error code
  74.         exit $rc        # if the command failed
  75.     fi
  76. }
  77.  
  78.  
  79.  
  80. #
  81. # This routine will create the file which is recognized by the desktop
  82. # as an active icon, and call tagprinter to put the right tag on it.
  83. #
  84. create_activeicon()
  85. {
  86.     # If we have no type, then give up and return
  87.     #
  88.     if [ "$rt" = "" ]; then
  89.     return 0
  90.     fi
  91.  
  92.     # If the icon directory doesn't exist, give up and return.
  93.     #
  94.     if [ ! -d $ACTIVEICON_DIR ]; then
  95.     return 0
  96.     fi
  97.  
  98.     # If the activeicon template file doesn't exist, give up and return.
  99.     #
  100.     if [ ! -f $ACTIVEICON_TEMPLATE_FILENAME ]; then
  101.     return 0
  102.     fi
  103.  
  104.     # First thing: install the activeicon file for printer $nam.
  105.     #
  106.     cp $ACTIVEICON_TEMPLATE_FILENAME $ACTIVEICON_DIR/$nam > /dev/null 2>&1
  107.  
  108.     # Make sure lp can write the file so it can tag it.
  109.     #
  110.     chown lp.lp $ACTIVEICON_DIR/$nam > /dev/null 2>&1
  111.  
  112.     # Set some defines to make tagging easier.
  113.     # The base (type of printer) tags
  114.     #
  115.     Dumb=66048            # 0x10200
  116.     DumbColor=66080        # 0x10220
  117.     Raster=66112        # 0x10240
  118.     ColorRaster=66144        # 0x10260
  119.     Plotter=66176        # 0x10280
  120.     PostScript=66208        # 0x102A0
  121.     ColorPostScript=66240    # 0x102C0
  122.     MonoPostScript=66272    # 0x102E0
  123.  
  124.     # And now the state modifiers for those type tags:
  125.     #
  126.     Networked=8            # 0x8
  127.  
  128.     # Set tag template based on printer type:
  129.     # Parse printer type and set the basetag.
  130.     #
  131.     case $rt in
  132.     Dumb|DUMB|dumb)
  133.         printertype=$Dumb
  134.         ;;
  135.     DumbColor|DUMBCOLOR|dumbcolor|Color|COLOR|color)
  136.         printertype=$DumbColor
  137.         ;;
  138.     Raster|RASTER|raster)
  139.         printertype=$Raster
  140.         ;;
  141.     ColorRaster|COLORRASTER|colorraster)
  142.         printertype=$ColorRaster
  143.         ;;
  144.     Plotter|PLOTTER|plotter)
  145.         printertype=$Plotter
  146.         ;;
  147.     PostScript|POSTSCRIPT|postscript)
  148.         printertype=$PostScript
  149.         ;;
  150.     ColorPostScript|COLORPOSTSCRIPT|colorpostscript)
  151.         printertype=$ColorPostScript
  152.         ;;
  153.     MonoPostScript|MONOPOSTSCRIPT|monopostscript)
  154.         printertype=$MonoPostScript
  155.         ;;     
  156.     *)    # XXX we just die silently if there's an unrecognized type.
  157.         # this is ok since we wouldn't know what to tag it anyways.
  158.         return 0
  159.         ;;
  160.     esac          
  161.  
  162.     # If we're a remote printer, add the "networked" modifier onto the tag
  163.     #
  164.     if [ -n "$rh" ]; then  
  165.     printertype=`expr $printertype + $Networked`
  166.     fi
  167.  
  168.     /usr/lib/print/tagprinter $nam $printertype > /dev/null 2>&1
  169.  
  170.     return 0
  171. }
  172.  
  173.  
  174. #
  175. # This routine will install the printer icons on the desktop
  176. #
  177. install_icon()
  178. {
  179.     # OK, first create the installed printer active icon file
  180.     # which will be installed into the desktop.
  181.     #
  182.     create_activeicon
  183.  
  184.     return 0
  185. }
  186.  
  187. #
  188. # This function creates a number of printing support directories
  189. #
  190. create_support_dirs()
  191. {
  192.     # Create a printer options settings directory for the printer
  193.     #
  194.     if [ ! -d "$SETTINGS_DIR" ]; then
  195.     mkdir -p $SETTINGS_DIR
  196.         chmod 755 $SETTINGS_DIR
  197.         chown lp.sys $SETTINGS_DIR
  198.     fi
  199.     if [ ! -d "$SETTINGS_DIR/$nam" ]; then
  200.         mkdir $SETTINGS_DIR/$nam
  201.         chmod 777 $SETTINGS_DIR/$nam
  202.         chown lp.sys $SETTINGS_DIR/$nam
  203.     fi
  204.  
  205.     # Create a graphical options interface directory
  206.     #
  207.     if [ ! -d "$INTERGUI_DIR" ]; then
  208.     mkdir -p $INTERGUI_DIR         
  209.     chmod 755 $INTERGUI_DIR
  210.     chown lp.sys $INTERGUI_DIR
  211.     fi
  212.     if [ ! -d "$INTERGUI_DIR/ELF" ]; then
  213.     mkdir $INTERGUI_DIR/ELF         
  214.     chmod 755 $INTERGUI_DIR/ELF
  215.     chown lp.sys $INTERGUI_DIR/ELF
  216.     fi
  217.  
  218.     # Create a POD directory
  219.     #
  220.     if [ ! -d "$POD_DIR" ]; then
  221.     mkdir -p $POD_DIR
  222.     chmod 755 $POD_DIR
  223.     chown lp.sys $POD_DIR
  224.     fi
  225.  
  226.     return 0
  227. }
  228.  
  229.  
  230. #
  231. # This function installs the Printer Option Panel program
  232. # (a.k.a. graphical model file) if it is available
  233. #
  234. install_guimodel()
  235. {
  236.     # First install the gui model program
  237.  
  238.     # If this is a network printer we copy the graphical options
  239.     # panel from the host gui interface dir to the client 
  240.     # interface dir. We save some space by linking the program
  241.     # if the client and server are the same machine.
  242.     #
  243.     if [ -n "$rh" ]; then
  244.     if [ "$rh" = "`/usr/bsd/hostname`" ]; then
  245.            if [ -x $INTERGUI_DIR/ELF/$rp.gui ]; then
  246.             ln -s $INTERGUI_DIR/ELF/$rp.gui $INTERGUI_DIR/ELF/$nam.gui
  247.        fi
  248.        if [ -x $INTERGUI_DIR/$rp.gui ]; then
  249.                 ln -s $INTERGUI_DIR/$rp.gui $INTERGUI_DIR/$nam.gui
  250.        fi
  251.     else
  252.         rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/ELF/$rp.gui \
  253.             $INTERGUI_DIR/ELF/$nam.gui 2>/dev/null
  254.         if [ $? -ne 0 ]; then
  255.             rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_INTERGUI_DIR/$rp.gui \
  256.                 $INTERGUI_DIR/$nam.gui 2>/dev/null
  257.         fi
  258.     fi
  259.     else
  260.     # If the printer is local make links instead of copying,
  261.     # to save some space.
  262.     #
  263.         if [ -x $MODELGUI_DIR/ELF/$mod.gui ]; then
  264.         ln -s $MODELGUI_DIR/ELF/$mod.gui $INTERGUI_DIR/ELF/$nam.gui
  265.     fi
  266.         if [ -x $MODELGUI_DIR/$mod.gui ]; then
  267.         ln -s $MODELGUI_DIR/$mod.gui $INTERGUI_DIR/$nam.gui
  268.     fi
  269.     fi
  270.  
  271.     # Now install the app-defaults
  272.  
  273.     # If this is a network printer we need to copy the graphical
  274.     # options panel app-defaults file to the spooling system
  275.     # app-defaults subdir.
  276.     #
  277.     if [ -n "$rh" ]; then
  278.     # Parse the interface file on the remote machine for the
  279.     # class name of the options panel.
  280.     #
  281.     guiclass=`rsh $rh -n -l $REMOTE_LOGIN_ID \
  282.         "/bin/sh -c \"egrep '^GUI_CLASS' $REMOTE_INTER_DIR/$rp\"" \
  283.         2>/dev/null`
  284.     if [ \( $? -eq 0 \) -a \( -n "$guiclass" \) ]; then
  285.         guiclass=`expr "$guiclass" : '^GUI_CLASS=\(.*\)'`
  286.  
  287.         # If we have a GUI class name...
  288.         #
  289.         if [ -n "$guiclass" ]; then
  290.         # Create the app-defaults subdir
  291.         #
  292.             if [ ! -d "$SPOOL_APP_DEFS_DIR" ]; then
  293.             mkdir -p $SPOOL_APP_DEFS_DIR
  294.                 chmod 755 $SPOOL_APP_DEFS_DIR
  295.                 chown lp.sys $SPOOL_APP_DEFS_DIR
  296.         fi
  297.             if [ ! -d "$SPOOL_APP_DEFS_DIR/$nam" ]; then
  298.                 mkdir $SPOOL_APP_DEFS_DIR/$nam
  299.                 chmod 755 $SPOOL_APP_DEFS_DIR/$nam
  300.                 chown lp.sys $SPOOL_APP_DEFS_DIR/$nam
  301.             fi
  302.  
  303.         # Copy the app-defaults file from the remote host
  304.         # to the spooler app-defaults subdir. Note that
  305.         # if LANG is set and is something other than "C"
  306.         # we copy over that app-default file.
  307.         #
  308.         apprcp=1
  309.         if [ \( "$LANG" != "" \) -a \( "$LANG" != "C" \) ]; then
  310.                 rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_LANG_APP_DIR/$guiclass \
  311.                 $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
  312.             apprcp=$?
  313.         fi
  314.         if [ $apprcp -ne 0 ]; then
  315.                 rcp $REMOTE_LOGIN_ID@$rh:$REMOTE_APP_DEFS_DIR/$guiclass \
  316.                     $SPOOL_APP_DEFS_DIR/$nam/$guiclass 2>/dev/null
  317.         fi
  318.         fi
  319.     fi
  320.     fi
  321.  
  322.     return 0
  323. }
  324.  
  325.  
  326. #
  327. # This function installs the POD files. It is the caller's responsibilty
  328. # to ensure that the printer is local
  329. #
  330. install_pod()
  331. {
  332.     # Install the POD files for a local printer. Notice that we
  333.     # do a straight copy of the status and log files but the config
  334.     # file is copied by nawk which edits the 'Port Path' entry to
  335.     # contain the device port pathname.
  336.     #
  337.     if [ -d $DATA_DIR ]; then
  338.     if [ -f $DATA_DIR/$mod.status ]; then 
  339.             cp $DATA_DIR/$mod.status $POD_DIR/$nam.status 2>/dev/null
  340.         rcexit
  341.         chown lp.lp $POD_DIR/$nam.status
  342.         chmod 0644 $POD_DIR/$nam.status
  343.     fi
  344.     if [ -f $DATA_DIR/$mod.config ]; then 
  345.         nawk -F\| '{
  346.         if ($1 ~ /^[ ]*Port[ ]+Path/) {
  347.             printf("%s| %s\n", $1, portdev)
  348.         } else {
  349.             printf("%s\n", $0)
  350.         }
  351.         }' portdev=$dev $DATA_DIR/$mod.config > \
  352.                     $POD_DIR/$nam.config 2>/dev/null
  353.         rcexit
  354.         chown lp.lp $POD_DIR/$nam.config
  355.         chmod 0644 $POD_DIR/$nam.config
  356.     fi
  357.     if [ -f $DATA_DIR/$mod.log ]; then 
  358.             cp $DATA_DIR/$mod.log $POD_DIR/$nam.log 2>/dev/null
  359.         rcexit
  360.         chown lp.lp $POD_DIR/$nam.log
  361.         chmod 0644 $POD_DIR/$nam.log
  362.     fi
  363.     fi
  364.  
  365.     return 0
  366. }
  367.  
  368.  
  369. #
  370. # Remove the active icon file for a printer.  This is separated from
  371. # remove_impressario because when changing connection (lputil replace)
  372. # the printer manager gets really messed up if the icon is removed.
  373. #
  374. remove_activeicon()
  375. {
  376.     # Remove the active icon.
  377.     #
  378.     rm -f $ACTIVEICON_DIR/$nam
  379. }
  380.  
  381. #
  382. # Change the permissions on the device as specified in the config file.
  383. # We do this because SCSI printers have fake devices for lpsched to
  384. # open, but actually use a different device for printing.  This whole
  385. # mess should be fixed.
  386. #
  387. fix_real_device()
  388. {
  389.     if [ -f $POD_DIR/$nam.config ]
  390.     then
  391.         real_device=`nawk -F\| '/^[ ]*Port[ ]+Path/ {
  392.         if (match($2, /[^ ]+/)) {
  393.         device = substr($2, RSTART, RLENGTH);
  394.         printf("%s", device);
  395.         }
  396.         exit
  397.         }' $POD_DIR/$nam.config 2>/dev/null`
  398.     
  399.         if [ -n "$real_device" -a "$real_device" != "$dev" ]
  400.         then
  401.         chmod 600 $real_device
  402.         chown root.sys $real_device
  403.         fi
  404.     fi
  405. }
  406.  
  407. #
  408. # This routine would remove the GUI interface files and
  409. # printer database file while removing an existing printer.
  410. #
  411. remove_impressario()
  412. {
  413.     # Remove the printer options settings directory
  414.     #
  415.     rm -rf $SETTINGS_DIR/$nam
  416.  
  417.     # Remove the graphical options panel
  418.     #
  419.     rm -f $INTERGUI_DIR/ELF/$nam.gui
  420.     rm -f $INTERGUI_DIR/$nam.gui
  421.  
  422.     # Remove the graphical options panel app-defaults
  423.     #
  424.     rm -rf $SPOOL_APP_DEFS_DIR/$nam
  425.  
  426.     # Remove the POD files
  427.     #
  428.     if [ -d $POD_DIR ]; then
  429.     fix_real_device
  430.         rm -f $POD_DIR/$nam.status
  431.         rm -f $POD_DIR/$nam.config 
  432.         rm -f $POD_DIR/$nam.log
  433.     fi
  434.   
  435.     # Remove the psrip paramaters directory for the printer
  436.     #
  437.     if [ -d $PSRIP_PARAMS_DIR/$nam ]; then
  438.        rm -rf $PSRIP_PARAMS_DIR/$nam
  439.     fi
  440.  
  441.     return 0
  442.  
  443. }
  444.  
  445. #
  446. # Remove a printer, including all the impressario stuff.
  447. #
  448. remove_printer()
  449. {
  450.     nam=$1
  451.     # Cancel any outstanding print requests
  452.     #
  453.     cancel `lpstat -o$nam | awk '{ print $1 }'` >/dev/null 2>&1
  454.  
  455.     # Get the device pahtname from the member file
  456.     #
  457.     dev=`cat $MEMBER_DIR/$nam 2> /dev/null`
  458.  
  459.     # Remove the printer
  460.     #
  461.     /usr/lib/lpadmin -x$nam
  462.     rc=$?
  463.  
  464.     if [ "$rc" != 0 ]; then
  465.         exit $rc
  466.     fi
  467.  
  468.     # Old style printers had "/dev/printername" linked to their
  469.     # device.
  470.     #
  471.     if [ -f /dev/$nam ]; then
  472.         rm -f /dev/$nam
  473.     fi
  474.  
  475.     # If the printer was local and there are no other printers
  476.     # connected to this port, change the owner to root.sys and
  477.     # the permissions to something safe.
  478.     #
  479.     if [ \( -n "$dev" \) -a \( "$dev" != "/dev/null" \) ]; then
  480.         grep "$dev" $MEMBER_DIR/* > /dev/null 2>&1
  481.         if [ $? = 1 ]; then
  482.         chmod 600 $dev
  483.         chown root.sys $dev
  484.         fi
  485.     fi
  486.  
  487.     # Remove all the Impressario files.
  488.     #
  489.     remove_impressario
  490.     remove_activeicon
  491. }
  492.  
  493. #
  494. # Trap handler for when we have a problem installing
  495. #
  496. install_error()
  497. {
  498.     unset -e
  499.     trap '' 0 1 2 3 15
  500.     echo "Error installing printer '$1'" 1>&2
  501.     remove_printer $1
  502.     exit 1
  503. }
  504.  
  505. #
  506. # This routine will install the GUI model files and printer 
  507. # database files while adding a new printer.
  508. #
  509. install_impressario()
  510. {
  511.     # If anything goes wrong with impr stuff, abort
  512.     set -e
  513.     trap 'install_error $nam' 0 1 2 3 15
  514.  
  515.     # Now install the printer's active icon in the desktop.
  516.     #
  517.     install_icon
  518.  
  519.     # Create the printing support directories
  520.     #
  521.     create_support_dirs
  522.  
  523.     # If the printer is local install the POD files
  524.     #
  525.     if [ -z "$rh" ]; then
  526.     install_pod
  527.     fi
  528.  
  529.     #
  530.     # Remove error handling, because install_guimodel uses non-zero
  531.     # exit status to test existence of remote gui modelf files.  That
  532.     # code shouldn't ever be used anymore because of the "addnet"
  533.     # command, but it's still there so it should still work
  534.     #
  535.     unset -e
  536.     trap '' 0 1 2 3 15
  537.  
  538.     # Install the graphical options panel
  539.     #
  540.     install_guimodel
  541.  
  542.     return 0
  543. }
  544.  
  545. #########################################################################
  546. #
  547. # Main program
  548. #
  549.  
  550. #
  551. # Start in a base directory
  552. #
  553. cd $SPOOL_DIR
  554.  
  555. #
  556. # Pick the primary function we are to perform
  557. #
  558. case $1 in
  559.     getinfo)
  560.     #
  561.     # getinfo <printername>
  562.     #
  563.     # This option is used to find various pieces of information
  564.     # about an installed printer.  The output format is multilple
  565.     # lines of keyword / value pairs separated by "="
  566.     #
  567.     shift
  568.     nam=$1
  569.     if [ -z "$nam" ]; then
  570.         echo "No printer name was specified." 1>&2
  571.         exit 1
  572.     fi
  573.     i=$nam
  574.     if [ -r class/$i ]; then
  575.         # If <printername> is a class, use the first member of the class.
  576.         #
  577.         i=`line < class/$i`
  578.     fi
  579.     cd interface
  580.     if [ ! -f $i ]; then
  581.         echo "non-existent" 1>&2
  582.         exit 2
  583.     else
  584.         egrep \
  585.         "^NAME=|^TYPE=|^HOSTNAME=|^HOSTPRINTER=|^BAUDRATE=|^STTYPARAMS=" $i
  586.         exit $?
  587.     fi
  588.     ;;
  589.     list)
  590.     /usr/lib/print/modelinfo
  591.     ;;
  592.     replacenet|addnet)
  593.     delete=1;
  594.     if [ "$1" = "replacenet" ]; then
  595.         delete=0
  596.     fi
  597.     #
  598.     # Add a networked printer
  599.     #
  600.     # addnet <host> <printer> <name> [<nettype>]
  601.     host=$2
  602.     printer=$3
  603.     nam=$4
  604.     type=
  605.     if [ $# -gt 4 ]; then
  606.         type="-t $5"
  607.     fi
  608.     # Install or replace the printer.  Installing a printer
  609.     # overwrites any printer or class with the same name.  It is
  610.     # the caller's responsibility to check for duplicate names.
  611.     #
  612.     # Replacing a printer changes the device and model for a
  613.         # printer, but doesn't blow away the queue.
  614.     #
  615.     if [ $delete -eq 1 ]; then
  616.         /usr/lib/lpadmin -x$nam > /dev/null 2>&1
  617.     fi
  618.  
  619.     # Unconditionally remove the Impressario stuff.  If we're replacing
  620.     # an Impressario printer with a non-Impressario printer, we need to
  621.     # do this to make sure all the extra stuff gets removed.
  622.     #
  623.     remove_impressario
  624.  
  625.     ####
  626.     # Make sure all relevant directories are available
  627.     ####
  628.     create_support_dirs
  629.  
  630.     /usr/lib/print/instnetpr $type $host $printer $nam
  631.     rc=$?
  632.     if [ $rc != 0 ]; then
  633.         exit $rc
  634.     fi
  635.     ####
  636.     # Enable the printer
  637.     ####
  638.     enable $nam > /dev/null 2>&1
  639.     /usr/lib/accept $nam > /dev/null 2>&1
  640.     ;;
  641.     replace|add)
  642.     delete=1
  643.     if [ "$1" = "replace" ]; then
  644.         delete=0
  645.     fi
  646.     #
  647.     # Add a new printer
  648.     #
  649.     # add <dev> <model> <name> [OPT=xxx ...]
  650.     #
  651.     # where:
  652.     #
  653.     # <dev> is the pathname to the device
  654.     # <model> is the name of the model script to use
  655.     # <name> is the name the new printer will have
  656.     # OPT=xxx is a model modifier in which "OPT="
  657.     # lines in model are changed to "OPT=xxx".
  658.     # Multiple OPT= can be specified.
  659.     #
  660.     dev=$2
  661.     mod=$3
  662.     nam=$4
  663.     shift;shift;shift;shift
  664.     ERRNOMOD="No such printer model as \"$mod\"."
  665.     ERRNODEV="Unable to write to device \"$dev\"."
  666.     ERRNONAM="No printer name was specified."
  667.     ERRLOGIN="Logins are currently enabled on this port."
  668.     ERRMODEM="A modem is currently enabled on this port."
  669.  
  670.     # Check for existence of printer model.
  671.     #
  672.     if [ ! -r "model/${mod}" ]; then
  673.         echo $ERRNOMOD 1>&2
  674.         exit 1
  675.     fi
  676.  
  677.         # Check the ~lp/devices is created if needed. 
  678.         # Some printer drivers use this and the higher level 
  679.         # install utility is supposed to create this directory.
  680.         # Check here in case future drivers do not (easy to miss
  681.         # since most developers systems would have it and would
  682.         # assume it is a standard lp sub-dir -- it is not).
  683.         # Defensive programming.
  684.  
  685.         DIRNAME=`dirname $dev`
  686.         if [ "$DIRNAME" = "/var/spool/lp/devices" ] ; then
  687.            if [ ! -d /var/spool/lp/devices ] ; then
  688.               mkdir /var/spool/lp/devices
  689.               chmod 0755 /var/spool/lp/devices
  690.               chown lp.sys /var/spool/lp/devices
  691.            fi
  692.            if [ ! -c $dev ] ; then
  693.               mknod $dev c 1 2
  694.               chmod 0666 $dev
  695.               chown lp.sys $dev
  696.            fi
  697.         fi
  698.  
  699.     # Verify that device is there.
  700.     #
  701.     if [ ! -w $dev ]; then
  702.         echo $ERRNODEV 1>&2
  703.         exit 1
  704.     fi
  705.  
  706.     # Make sure there's a name for the new printer.
  707.     #
  708.     if [ -z "$nam" ]; then
  709.         echo $ERRNONAM 1>&2
  710.         exit 1
  711.     fi
  712.  
  713.     # Check for gettys or modems enabled if the device
  714.     # is a serial port.
  715.     #
  716.     if expr X"$dev" : ".*tty" > /dev/null; then
  717.         # Watch out for ttyd1 vs. ttym1 vs. ttyf1 etc.
  718.         #
  719.         ttynum=`expr X"$dev" : ".*tty[dmf]\([0-9]*\)"`
  720.         re="tty[dmf]$ttynum[^0-9]"
  721.         if who -l | grep $re > /dev/null; then
  722.         echo $ERRLOGIN 1>&2
  723.         exit 1
  724.         fi
  725.         ml=`grep "^[^#].*$re" /usr/lib/uucp/Devices 2> /dev/null`
  726.         if [ -n "$ml" ]; then
  727.         echo $ERRMODEM 1>&2
  728.         exit 1
  729.         fi
  730.     fi
  731.  
  732.     # Give exclusive control of device to lp
  733.     #
  734.     if [ "$dev" != "/dev/null" ]; then
  735.         chown lp  $dev
  736.         chmod 600 $dev
  737.     fi
  738.  
  739.     # Assemble substitution arguments so they can be done in
  740.     # one sed command.
  741.     #
  742.     for i
  743.     do
  744.         lhs=`expr "$i" : "\(.*\)="`
  745.         if [ -n "$lhs" ]; then
  746.         sc="${sc}-e 's@^${lhs}=.*@${i}@' "
  747.         fi
  748.     done
  749.     if [ -z "$sc" ]; then
  750.         cp model/${mod} /tmp/$nam
  751.     else
  752.         # recursive quoting in $sc requires this nastiness
  753.         #
  754.         sh -c "sed $sc model/${mod} > /tmp/$nam"
  755.     fi
  756.  
  757.     # We don't want any partial adds
  758.     #
  759.     trap '' 1 2 3 15
  760.  
  761.     # Install or replace the printer.  Installing a printer
  762.     # overwrites any printer or class with the same name.  It is
  763.     # the caller's responsibility to check for duplicate names.
  764.     #
  765.     # Replacing a printer changes the device and model for a
  766.         # printer, but doesn't blow away the queue.
  767.     #
  768.     if [ $delete -eq 1 ]; then
  769.         /usr/lib/lpadmin -x$nam > /dev/null 2>&1
  770.     fi
  771.  
  772.     # Unconditionally remove the Impressario stuff.  If we're replacing
  773.     # an Impressario printer with a non-Impressario printer, we need to
  774.     # do this to make sure all the extra stuff gets removed.
  775.     #
  776.     remove_impressario
  777.  
  778.     /usr/lib/lpadmin -p$nam -v$dev -i/tmp/$nam
  779.     rc=$?
  780.     rm -f /tmp/$nam
  781.     if [ $rc != 0 ]; then
  782.         remove_printer $nam  # No partial printers!!
  783.         exit 1
  784.     fi
  785.     df=`cat $SPOOL_DIR/default 2> /dev/null`
  786.     if [ -z "$df" ]; then
  787.         /usr/lib/lpadmin -d$nam
  788.     fi
  789.     enable $nam > /dev/null 2>&1
  790.  
  791.     # Enable the printer
  792.     #
  793.     /usr/lib/accept $nam > /dev/null 2>&1
  794.  
  795.     # Install all the Impressario support
  796.     #
  797.     RTYPE=`egrep "^TYPE=" $SPOOL_DIR/interface/$nam`
  798.     rt="`echo "$RTYPE" | sed 's/TYPE=//'`"
  799.      RHOST=`egrep "^HOSTNAME=" $SPOOL_DIR/interface/$nam`
  800.      rh="`echo "$RHOST" | sed 's/HOSTNAME=//'`"
  801.      RPRTR=`egrep "^HOSTPRINTER=" $SPOOL_DIR/interface/$nam`
  802.     rp="`echo "$RPRTR" | sed 's/HOSTPRINTER=//'`"
  803.  
  804.     #
  805.     # Always call this routine last, it has side effects
  806.     #
  807.     install_impressario
  808.     exit 0
  809.     ;;
  810.     remove)
  811.     #
  812.     # lputil remove <printer or class> <move dest>
  813.     #
  814.     # remove a printer after optionally moving all of its
  815.     # outstanding requests to another destination.
  816.     #
  817.     nam=$2
  818.     mvdest=$3
  819.     if [ -z "$nam" ]; then
  820.         echo "No printer name was specified to delete." 1>&2
  821.         exit 2
  822.     fi
  823.  
  824.     # We don't want any partial deletes
  825.     #
  826.     trap '' 1 2 3 15
  827.  
  828.     # Close off both ends of the print queue
  829.     #
  830.     /usr/lib/reject -r"*deletion in progress*" $nam > /dev/null 2>&1
  831.     disable -c -r"*deletion in progress*" $nam > /dev/null 2>&1
  832.  
  833.     # Move queue if needed
  834.     #
  835.     if [ -n "$mvdest" ]; then
  836.         /usr/lib/lpmove $nam $mvdest > /dev/null 2>&1
  837.     fi
  838.  
  839.     remove_printer $nam
  840.     exit 0
  841.     ;;
  842.     chkremote)
  843.     #
  844.     # lputil chkremote <machine> <remote login id>
  845.     #
  846.     # chkremote will list the printers on a remote host.
  847.     #
  848.     if /sbin/chkconfig network; then
  849.         :
  850.     else
  851.         echo "Networking has not been enabled on this system." 1>&2
  852.         exit 1
  853.     fi
  854.     if [ -z "$2" ]; then
  855.         echo "No remote hostname was specified for chkremote." 1>&2
  856.         exit 2
  857.     fi
  858.  
  859.     /usr/lib/print/listprinters $2 2>/dev/null
  860.     rcexit
  861.     exit 0
  862.     ;;
  863.     remoteinfo)
  864.     #
  865.     # lputil remoteinfo <machine> <printer> <login id>
  866.     #
  867.     # Get the information associated with a printer located
  868.     # on a remote machine.
  869.     #
  870.     if [ -z "$4" ]; then
  871.         REMOTE_LOGIN_ID=lp
  872.     else
  873.         REMOTE_LOGIN_ID=$4
  874.     fi
  875.     NAME=
  876.     TYPE=
  877.     HOSTNAME=
  878.     HOSTPRINTER=
  879.     BAUDRATE=
  880.     STTYPARAMS=
  881.     eval `rsh $2 -n -l $REMOTE_LOGIN_ID \
  882.             "/bin/sh -c \"/usr/lib/lputil getinfo $3\"" 2>/dev/null` \
  883.             2> /dev/null 1>&2 0<&1
  884.  
  885.     # If we don't come up with all of the keywords, we can
  886.     # try to guess on some.
  887.     #
  888.     if [ -z "$TYPE" ]; then
  889.         ps=`rsh $2 -n -l $REMOTE_LOGIN_ID \
  890.             "/bin/sh -c \"grep PostScript \
  891.             $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
  892.         if [ -n "$ps" ]; then
  893.         NAME="LaserWriter"
  894.         TYPE=PostScript
  895.         else
  896.         color=`rsh $2 -n -l $REMOTE_LOGIN_ID \
  897.                     "/bin/sh -c \"grep 'color printer' \
  898.                     $OLD_SPOOL_DIR/interface/$3 2>/dev/null\""`
  899.         if [ -n "$color" ]; then
  900.             NAME="Color Printer"
  901.             TYPE=Color
  902.         fi
  903.         fi
  904.     fi
  905.     if [ -z "$HOSTNAME" -a -n "$host" ]; then
  906.         HOSTNAME=$host
  907.     fi
  908.     if [ -z "$HOSTPRINTER" -a -n "$printer" ]; then
  909.         HOSTPRINTER=$printer
  910.     fi
  911.     echo NAME=\"$NAME\"
  912.     echo TYPE=$TYPE
  913.     echo HOSTNAME=$HOSTNAME
  914.     echo HOSTPRINTER=$HOSTPRINTER
  915.     echo BAUDRATE=$BAUDRATE
  916.     echo STTYPARAMS=$STTYPARAMS
  917.     exit 0
  918.     ;;
  919.     printq)
  920.     #
  921.     # lputil printq <machine> <printer> <login id>
  922.     #
  923.     # printq will return the lpstat information from
  924.     # a local or remote print queue
  925.     #
  926.     if [ -z "$2" -o "`hostname`" = "$2" ]; then
  927.         /usr/bin/lpstat -o$3 2> /dev/null 2>&1
  928.         exit 3
  929.     fi
  930.     if [ -z "$4" ]; then
  931.         REMOTE_LOGIN_ID=lp
  932.     else
  933.         REMOTE_LOGIN_ID=$4
  934.     fi
  935.     if /sbin/chkconfig network; then
  936.         :
  937.     else
  938.         echo "Networking has not been enabled on this system." 1>&2
  939.         exit 1
  940.     fi
  941.     rsh $2 -n -l $REMOTE_LOGIN_ID \
  942.         "/bin/sh -c \"/usr/bin/lpstat -o$3 2> /dev/null\"" 2>&1
  943.     exit $?
  944.     ;;
  945.     *)
  946.     echo "lputil: invalid operation - $*" 1>&2
  947.     exit 2
  948.     ;;
  949. esac
  950.  
  951. #
  952. # Return a successful exit code
  953. #
  954. exit 0
  955.